// /**
//  ****************************************************************************************************
//  * @file        udp.c
//  * @author      正点原子团队(ALIENTEK)
//  * @version     V1.0
//  * @date        2023-08-26
//  * @brief       LWIP实验
//  * @license     Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
//  ****************************************************************************************************
//  * @attention
//  *
//  * 实验平台:正点原子 ESP32-S3 开发板
//  * 在线视频:www.yuanzige.com
//  * 技术论坛:www.openedv.com
//  * 公司网址:www.alientek.com
//  * 购买地址:openedv.taobao.com
//  *
//  ****************************************************************************************************
//  */

// #include "lwip_demo.h"


// int g_publish_flag = 0;/* 发布成功标志位 */
// static const char *TAG = "MQTT_EXAMPLE";
// char g_lcd_buff[100] = {0};

// /**
//  * @brief       错误日记
//  * @param       message     :错误消息
//  * @param       error_code  :错误码
//  * @retval      无
//  */
// static void log_error_if_nonzero(const char *message, int error_code)
// {
//     if (error_code != 0)
//     {
//         ESP_LOGE(TAG, "Last error %s: 0x%x", message, error_code);
//     }
// }

// /**
//  * @brief       注册接收MQTT事件的事件处理程序
//  * @param       handler_args:注册到事件的用户数据
//  * @param       base        :处理程序的事件库
//  * @param       event_id    :接收到的事件的id
//  * @param       event_data  :事件的数据
//  * @retval      无
//  */
// static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
// {
//     ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%" PRIi32 "", base, event_id);
//     esp_mqtt_event_handle_t event = event_data;
//     esp_mqtt_client_handle_t client = event->client;
//     int msg_id;

//     switch ((esp_mqtt_event_id_t)event_id)
//     {
//         case MQTT_EVENT_CONNECTED:      /* 连接事件 */
//             ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
//             msg_id = esp_mqtt_client_publish(client, "/topic/qos1", "data_3", 0, 1, 0);
//             ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);

//             msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 0);
//             ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);

//             msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);
//             ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);

//             msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");
//             ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
//             g_publish_flag = 1;
//             /* 订阅主题 */
//             msg_id = esp_mqtt_client_subscribe(client, DEVICE_SUBSCRIBE, 0);
//             ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
//             break;
//         case MQTT_EVENT_DISCONNECTED:   /* 断开连接事件 */

//             break;

//         case MQTT_EVENT_SUBSCRIBED:     /* 取消事件 */
//             ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
//             msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
//             ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
//             break;
//         case MQTT_EVENT_UNSUBSCRIBED:   /* 取消订阅事件 */
//             ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
//             break;
//         case MQTT_EVENT_PUBLISHED:      /* 发布事件 */
//             ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
//             break;
//         case MQTT_EVENT_DATA:           /* 接收数据事件 */
//             printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
//             printf("DATA=%.*s\r\n", event->data_len, event->data);

//             break;
//         case MQTT_EVENT_ERROR:

//             if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT)
//             {
//                 log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);
//                 log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);
//                 log_error_if_nonzero("captured as transport's socket errno",  event->error_handle->esp_transport_sock_errno);
//                 ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));
//             }

//             break;
//         default:
//             ESP_LOGI(TAG, "Other event id:%d", event->event_id);
//             break;
//     }
// }

// /**
//  * @brief       lwip_demo进程
//  * @param       无
//  * @retval      无
//  */
// void lwip_demo(void)
// {
//     char mqtt_publish_data[] = "alientek esp32-s3";
//     /* 设置客户端的信息量 */ 
//     esp_mqtt_client_config_t mqtt_cfg = {
//     .broker.address.hostname = HOST_NAME,                   /* MQTT地址 */
//     .broker.address.port = HOST_PORT,                       /* MQTT端口号 */
//     .broker.address.transport = MQTT_TRANSPORT_OVER_TCP,    /* TCP模式 */
//     .credentials.client_id = CLIENT_ID,                     /* 设备名称 */
//     .credentials.username = (char*)USER_NAME,               /* 产品ID */
//     .credentials.authentication.password = PASSWORD,        /* 计算出来的密码 */
//     };

//     esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);

//     esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
//     esp_mqtt_client_start(client);

//     while(1)
//     {
//         if (g_publish_flag == 1)
//         {
//             esp_mqtt_client_publish(client,DEVICE_PUBLISH,(char *)mqtt_publish_data,strlen(mqtt_publish_data),1,0);
//         }
        
//         vTaskDelay(1000);
//     }
// }

/**
 ****************************************************************************************************
 * @file        udp.c
 * @author      正点原子团队(ALIENTEK)
 * @version     V1.0
 * @date        2023-08-26
 * @brief       LWIP实验
 * @license     Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
 ****************************************************************************************************
 * @attention
 *
 * 实验平台:正点原子 ESP32-S3 开发板
 * 在线视频:www.yuanzige.com
 * 技术论坛:www.openedv.com
 * 公司网址:www.alientek.com
 * 购买地址:openedv.taobao.com
 *
 ****************************************************************************************************
 */

#include "lwip_demo.h"

int g_publish_flag = 0;/* 发布成功标志位 */
static const char *TAG = "MQTT_EXAMPLE";
char g_lcd_buff[100] = {0};

/**
 * @brief       错误日记
 * @param       message     :错误消息
 * @param       error_code  :错误码
 * @retval      无
 */
static void log_error_if_nonzero(const char *message, int error_code)
{
    if (error_code != 0)
    {
        ESP_LOGE(TAG, "Last error %s: 0x%x", message, error_code);
    }
}

/**
 * @brief       注册接收MQTT事件的事件处理程序
 * @param       handler_args:注册到事件的用户数据
 * @param       base        :处理程序的事件库
 * @param       event_id    :接收到的事件的id
 * @param       event_data  :事件的数据
 * @retval      无
 */
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
    ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%" PRIi32 "", base, event_id);
    esp_mqtt_event_handle_t event = event_data;
    esp_mqtt_client_handle_t client = event->client;
    int msg_id;

    switch ((esp_mqtt_event_id_t)event_id)
    {
        case MQTT_EVENT_CONNECTED:      /* 连接事件 */
            ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
            g_publish_flag = 1;
            
            /* 订阅主题 */
            msg_id = esp_mqtt_client_subscribe(client, DEVICE_SUBSCRIBE, 0);
            ESP_LOGI(TAG, "Subscribe to topic %s, msg_id=%d", DEVICE_SUBSCRIBE, msg_id);
            
            /* 发布连接成功消息 */
            msg_id = esp_mqtt_client_publish(client, DEVICE_PUBLISH, "ESP32-S3 connected", 0, 0, 0);
            ESP_LOGI(TAG, "Publish connection message, msg_id=%d", msg_id);
            break;
            
        case MQTT_EVENT_DISCONNECTED:   /* 断开连接事件 */
            ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
            g_publish_flag = 0;
            break;

        case MQTT_EVENT_SUBSCRIBED:     /* 订阅成功事件 */
            ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
            break;
            
        case MQTT_EVENT_UNSUBSCRIBED:   /* 取消订阅事件 */
            ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
            break;
            
        case MQTT_EVENT_PUBLISHED:      /* 发布事件 */
            ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
            break;
            
        case MQTT_EVENT_DATA:           /* 接收数据事件 */
            ESP_LOGI(TAG, "MQTT_EVENT_DATA");
            printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
            printf("DATA=%.*s\r\n", event->data_len, event->data);
            
            // 可以在这里添加处理接收到的数据的代码
            if (strncmp(event->topic, DEVICE_SUBSCRIBE, event->topic_len) == 0) {
                // 处理订阅主题的消息
                ESP_LOGI(TAG, "Received message on subscribed topic: %.*s", event->data_len, event->data);
            }
            break;
            
        case MQTT_EVENT_ERROR:
            ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
            if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT)
            {
                log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);
                log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);
                log_error_if_nonzero("captured as transport's socket errno",  event->error_handle->esp_transport_sock_errno);
                ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));
            }
            break;
            
        default:
            ESP_LOGI(TAG, "Other event id:%d", event->event_id);
            break;
    }
}

/**
 * @brief       lwip_demo进程
 * @param       无
 * @retval      无
 */
void lwip_demo(void)
{
    char mqtt_publish_data[] = "Hello from ALIENTEK ESP32-S3";
    
    /* 设置MQTT客户端配置 */ 
    esp_mqtt_client_config_t mqtt_cfg = {
    .broker = {
        .address.hostname = HOST_NAME,
        .address.port = HOST_PORT,
        .address.transport = MQTT_TRANSPORT_OVER_TCP,
    },
    .credentials = {
        .client_id = CLIENT_ID,
        .username = USER_NAME,
        .authentication.password = PASSWORD,
    },
};

    ESP_LOGI(TAG, "Connecting to MQTT server: %s", HOST_NAME);
    ESP_LOGI(TAG, "Client ID: %s", CLIENT_ID);
    ESP_LOGI(TAG, "Publish topic: %s", DEVICE_PUBLISH);
    ESP_LOGI(TAG, "Subscribe topic: %s", DEVICE_SUBSCRIBE);

    esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
    esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
    esp_mqtt_client_start(client);

    int message_count = 0;
    while(1)
    {
        if (g_publish_flag == 1)
        {
            // 定期发布消息
            snprintf(g_lcd_buff, sizeof(g_lcd_buff), "Message %d", message_count++);
            int msg_id = esp_mqtt_client_publish(client, DEVICE_PUBLISH, g_lcd_buff, 0, 0, 0);
            ESP_LOGI(TAG, "Published message %s, msg_id=%d", g_lcd_buff, msg_id);
        }
        
        vTaskDelay(5000 / portTICK_PERIOD_MS); // 每5秒发布一次消息
    }
}